package com.tbit.uqbike.webmanager.controller;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageInfo;
import com.tbit.common.utils.TraceUtil;
import com.tbit.uqbike.annos.OperateLog;
import com.tbit.uqbike.constant.UserConstant;
import com.tbit.uqbike.constant.UserConstants;
import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.Role;
import com.tbit.uqbike.object.pojo.dto.RoleCopyAddDTO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.AccountService;
import com.tbit.uqbike.service.business.RoleService;
import com.tbit.uqbike.webmanager.util.ServletUtils;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import com.tbit.utils.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.RequestContext;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 角色信息
 *
 * @author jing
 */
@RestController
@RequestMapping("/role")
public class RoleController extends BaseController {
    @Autowired
    private RoleService roleService;
    @Autowired
    private AccountService accountService;


    @GetMapping("/list")
    public JsonResult list(Role role, HttpServletRequest request) {
        LoginInfo login = BaseController.getLogin(request);
        if (!login.roleIsAdmin()) {
            //非管理账号
            if (UserConstant.USER_BRAND.equals(login.getType())) {
                //品牌账号
                role.setAccountId(login.getId());
            } else {
                //非品牌账号，查询当前账号所属的品牌的权限
                role.setAccountId(accountService.getBrandId(login.getId()));
            }
        } else {
            //管理员账号查询所有
            role.setAccountId(null);
        }
        startPage();
        role.setType(String.valueOf(getLogin(ServletUtils.getRequest()).getType()));
        List<Role> list = roleService.selectRoleList(role);
        return JsonResult.ok(list, (int) new PageInfo<>(list).getTotal());
    }

    /**
     * 根据品牌id和类型查询角色列表
     *
     * @param accountId
     * @param roleLevel
     * @return
     */
    @GetMapping("/listByBrandIdAndType")
    public Result<List<Role>> listByBrandIdAndType(Integer accountId, Integer roleLevel,HttpServletRequest request) {
        Assert.notNulls("缺少必要参数", accountId, roleLevel);
        LoginInfo login = getLogin(request);
        /*Role role = new Role();
        role.setAccountId(accountId);
        role.setRoleLevel(roleLevel.toString());*/
//        List<Role> list = roleService.selectRoleList(role);
        List<Role> list = roleService.getRolesByLoginUser(accountId,String.valueOf(roleLevel), login);
        return Result.success(list);
    }

    /**
     * 根据角色编号获取详细信息
     */
    @GetMapping(value = "/{roleId}")
    public JsonResult getInfo(@PathVariable Integer roleId) {
        return JsonResult.ok(roleService.selectRoleById(roleId));
    }

    @GetMapping("/export")
    public JsonResult export(Role role) {
        List<Role> list = roleService.selectRoleList(role);
        ExcelUtil<Role> util = new ExcelUtil<Role>(Role.class);
        return util.exportExcel(list, "角色数据");
    }


    /**
     * 新增角色
     */
    @PostMapping
    @OperateLog(module = ModuleEnum.ROLE, methods = MethodEnum.ROLE_ADD)
    public JsonResult add(@Validated @RequestBody Role role, HttpServletRequest request) {
        if (StrUtil.isNotEmpty(role.getRoleName()) && role.getRoleName().length() > 30){
            throw new BaseException("角色名称过长");
        }
        LoginInfo login = BaseController.getLogin(request);
        if (login.roleIsAdmin()) {
            //管理员角色要选择品牌
            Assert.notNull(role.getAccountId(), "请选择品牌");
        } else {
            //只允许品牌及以上账户操作
            if (!UserConstant.USER_BRAND.equals(login.getType())) {
                return JsonResult.fail("仅允许品牌及品牌以上账户进行操作", TraceUtil.getTraceIdByLocal());
            }
            role.setAccountId(login.getId());
        }
        Integer roleId = roleService.selectInsertRoleId();
        //全部统一不用前端传了，无用字段，但为了兼容以前的不能删
        role.setRoleId(roleId);
        role.setRoleCode(roleId.toString());
        role.setRoleValue(roleId.toString());
        role.setRoleKey(roleId + "_" + UUID.randomUUID());
        RequestContext context = getLogin(ServletUtils.getRequest()).context;
        if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) {
            return JsonResult.fail(context.getMessage("insert_role_name_exists"),TraceUtil.getTraceIdByLocal());
        } else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) {
            return JsonResult.fail(context.getMessage("insert_role_key_exists"),TraceUtil.getTraceIdByLocal());
        } else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleValueUnique(role))) {
            return JsonResult.fail(context.getMessage("insert_role_value_exists"),TraceUtil.getTraceIdByLocal());
        } else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleLevelCodeUnique(role))) {
            return JsonResult.fail(context.getMessage("insert_role_level_code_exists"),TraceUtil.getTraceIdByLocal());
        }
        return JsonResult.toAjax(roleService.insertRole(role), context);
    }

    @PostMapping("/copy/add")
    @OperateLog(module = ModuleEnum.ROLE, methods = MethodEnum.ROLE_COPY_ADD)
    public Result<Integer> copyAdd(@RequestBody @Validated RoleCopyAddDTO roleCodyDTO, HttpServletRequest request) {
        LoginInfo login = BaseController.getLogin(request);
        if (login.roleLowerThanBrand()) {
            return Result.error("仅允许品牌及品牌以上账户进行操作");
        }
        return roleService.copyAdd(roleCodyDTO, getLogin(ServletUtils.getRequest()).context);
    }

    /**
     * 修改保存角色
     */
    @PutMapping
    @OperateLog(module = ModuleEnum.ROLE, methods = MethodEnum.ROLE_EDIT)
    public JsonResult edit(@Validated @RequestBody Role role, HttpServletRequest request) {
        Assert.notNull(role.getRoleId(), "参数有误");
        LoginInfo login = BaseController.getLogin(request);
        if (roleService.isDefaultRole(role.getRoleId()) && !login.roleIsAdmin()) {
            //默认的角色不允许修改(除了超级管理员)
            return JsonResult.fail("系统角色禁止修改",TraceUtil.getTraceIdByLocal());
        }
        if (!UserConstant.USER_BRAND.equals(login.getType()) && !login.roleIsAdmin()) {
            return JsonResult.fail("仅允许品牌及品牌以上账户进行操作",TraceUtil.getTraceIdByLocal());
        }
        Role roleInDb = roleService.selectRoleById(role.getRoleId());
        role.setAccountId(roleInDb.getAccountId());
        /*已绑定账号不允许删除*/
        if (!role.getRoleLevel().equals(roleInDb.getRoleLevel()) && roleService.countUserRoleByRoleId(role.getRoleId()) > 0){
            return JsonResult.fail("已绑定账号不允许删除",TraceUtil.getTraceIdByLocal());
        }
        RequestContext context = getLogin(ServletUtils.getRequest()).context;
        if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) {
            return JsonResult.fail(context.getMessage("update_role_name_exists"),TraceUtil.getTraceIdByLocal());
        }
        return JsonResult.toAjax(roleService.updateRole(role), context);
    }


    /**
     * 绑定菜单权限
     *
     * @param role
     * @return
     */
    @PutMapping("/bindPerm")
    @OperateLog(module = ModuleEnum.ROLE, methods = MethodEnum.ROLE_BIND)
    public JsonResult bindPerm(@RequestBody Role role, HttpServletRequest request) {
        if (!BaseController.getLogin(request).roleIsAdmin() && roleService.isDefaultRole(role.getRoleId())) {
            //不是管理员不允许修改默认角色的菜单权限
            return JsonResult.fail("禁止修改默认角色的权限",TraceUtil.getTraceIdByLocal());
        }
        roleService.checkRoleAllowed(role);
        return JsonResult.toAjax(roleService.bindPerm(role), getLogin(ServletUtils.getRequest()).context);
    }

    /**
     * 状态修改
     */
    @PutMapping("/changeStatus")
    @OperateLog(module = ModuleEnum.ROLE, methods = MethodEnum.ROLE_EDIT)
    public JsonResult changeStatus(@RequestBody Role role) {
        roleService.checkRoleAllowed(role);
        return JsonResult.toAjax(roleService.updateRoleStatus(role), getLogin(ServletUtils.getRequest()).context);
    }

    /**
     * 删除角色
     */
    @DeleteMapping("/{roleIds}")
    @OperateLog(module = ModuleEnum.ROLE, methods = MethodEnum.ROLE_DEL)
    public JsonResult remove(@PathVariable Integer[] roleIds, HttpServletRequest request) {
        LoginInfo login = BaseController.getLogin(request);
        if (!UserConstant.USER_BRAND.equals(login.getType()) && !login.roleIsAdmin()) {
            return JsonResult.fail("仅允许品牌及品牌以上账户进行操作",TraceUtil.getTraceIdByLocal());
        }
        for (Integer roleId : roleIds) {
            if (roleService.isDefaultRole(roleId)) {
                throw new BaseException(SystemCodeEnum.SYS_ROLE_NOT_DEL);
            }
        }
        return JsonResult.toAjax(roleService.deleteRoleByIds(roleIds), getLogin(ServletUtils.getRequest()).context);
    }

    /**
     * 获取角色选择框列表
     */
    @GetMapping("/optionselect")
    public JsonResult optionselect(Role role) {
        return JsonResult.ok(roleService.selectRoleAll(role));
    }

    /**
     * @description: 获取当前登录用户能获取的全部角色
     * @author: mo.shanyong
     * @date: 2025/3/4 16:20
     * @param: request
     * @return: com.tbit.uqbike.object.view.JsonResult
     */
    @GetMapping("/getRoleList")
    public JsonResult getRoleListByUser(HttpServletRequest request){
        LoginInfo login = BaseController.getLogin(request);
        List<Role> roleList = roleService.getRoleListByUser(login);
        return JsonResult.ok(roleList);
    }
}
